package com.xnx.bincker.leader.controller;

import com.xnx.bincker.leader.exception.SystemException;
import com.xnx.bincker.leader.exception.permission.NoLoginException;
import lombok.extern.log4j.Log4j2;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@RestController
@Log4j2
@RequestMapping({"${server.error.path:${error.path:/error}}"})
public class ErrorController extends AbstractErrorController {
    private ErrorProperties errorProperties;
    private ErrorAttributes errorAttributes;
    public ErrorController(
            ErrorAttributes errorAttributes,
            ServerProperties serverProperties) {
        super(errorAttributes);
        errorProperties = serverProperties.getError();
        this.errorAttributes = errorAttributes;
    }

    @Override
    public String getErrorPath() {
        return errorProperties.getPath();
    }

    @RequestMapping
    public SystemException error(HttpServletRequest request, HttpServletResponse response){
        if(response.isCommitted()) return null;
        Throwable throwable = errorAttributes.getError(new ServletWebRequest(request));
        if(throwable instanceof SystemException){
            if(throwable instanceof NoLoginException){
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            }
            return (SystemException) throwable;
        }
        else{
            Map<String, Object> errorInfo = errorAttributes.getErrorAttributes(new ServletWebRequest(request), true);
            log.error(errorInfo);
            return () -> -1;
        }
    }
}
